﻿using Abp.Domain.Repositories;
using Choucius.Boilerplate9.PlasticContainers;
using Choucius.Boilerplate9.PTX;
using System.Threading.Tasks;
using System;
using Choucius.Boilerplate9.DtoBase;
using Choucius.Boilerplate9.Enum;
using Choucius.Boilerplate9.ProductContainerRelationships;

namespace Choucius.Boilerplate9.T4000
{
    /// <summary>
    /// T4000打印机
    /// </summary>
    public class T4000AppService : IT4000AppService
    {
        //private readonly IConfigurationRoot _configuration;
        private readonly IRepository<PlasticContainer, Guid> _plasticContainerRepository;
        private readonly IProductContainerRelationshipAppService _productContainerRelationshipAppService;

        /// <summary>
        /// 依赖注入
        /// </summary>
        /// <param name="plasticContainerRepository"></param>
        /// <param name="productContainerRelationshipAppService"></param>
        public T4000AppService(IRepository<PlasticContainer, Guid> plasticContainerRepository, IProductContainerRelationshipAppService productContainerRelationshipAppService)
        {
            _plasticContainerRepository = plasticContainerRepository;
            _productContainerRelationshipAppService = productContainerRelationshipAppService;
        }

        //public T4000AppService(IConfigurationRoot configuration, IRepository<PlasticContainer, Guid> plasticContainerRepository)
        //{
        //    _configuration = configuration;
        //    _plasticContainerRepository = plasticContainerRepository;
        //}

        /// <summary>
        /// 调用T4000打印机打印RFID标签，并保存标签信息
        /// </summary>
        /// <param name="ip">打印机IP地址</param>
        /// <param name="port">打印端口</param>
        /// <param name="data">需要打印的数据</param>
        /// <returns></returns>
        public async Task<ResponseDto> PrintAndSaveAsync(string ip, int port, string data)
        {
            if (string.IsNullOrEmpty(ip) || string.IsNullOrEmpty(data) || port <= 0)
            {
                return new ResponseDto()
                {
                    Code = 404,
                    Message = $"空数据：ip={ip}, port={port}, data={data}。"
                };
            }
            // 打印
            var response = CallPTX(ip, port, data);

            // 获取吸塑盒名称
            string plasticContainerErpId = data.Substring(0, 8);
            string plasticContainerName = _productContainerRelationshipAppService.GetPlasticContainerNameByPlasticContainerErpId(plasticContainerErpId);

            // 保存
            var entity = new PlasticContainer
            {
                RFID = data,
                EPC = data + "FFFFFFFF", // 打印标签完成直接初始化
                Status = LabelStatus.Initialization, // 打印标签完成直接初始化
                CreationTime = DateTime.Now,
                CreatorUserId = 0,
                PlasticContainerName = plasticContainerName // TODO：吸塑盒名称暂存在库位字段，后期增加字段
            };
            await _plasticContainerRepository.InsertAsync(entity); // 使用InsertAsync方法保存实体

            //// 读取
            //var query = await _plasticContainerRepository.GetAllAsync();
            //int totalCount = query.Count();
            //query = query
            //    .OrderByDescending(e => e.Id);
            //return Mapping(query, totalCount);

            return response;
        }

        private ResponseDto CallPTX(string ip, int port, string data)
        {
            //string data = "0218C008";
            var response = new ResponseDto
            {
                Code = 200,
                Message = "打印标签完成。"
            };

            /* OPEN THE CONNECTION */
            // ‌普印力打印机的默认端口是9100‌。这个端口主要用于打印功能，是打印机与计算机或其他设备通信的主要通道‌。此外，普印力打印机还支持其他网络管理功能，如远程配置和状态监控，这些功能通常使用80和443端口‌。
            //int resultOfOpeneThernet = PTXLIB.openethernet("192.168.4.51", 9100);
            int resultOfOpeneThernet = PTXLIB.openethernet(ip, port);
            if (resultOfOpeneThernet == Convert.ToInt32(ReturnValue.PTXA_INVALID))
            {
                response.Code = resultOfOpeneThernet;
                response.Message = "网络连接失败！";
                return response;
            }

            /* INIT THE DLL */
            PTXLIB.PTXA_DLLinit();

            //PTXLIB.PTXA_JobSetup(1, 2360);//设置纸张宽度，单位1/1000英寸
            //PTXLIB.PTXA_JobSetup(2, 787);//设置纸张长度，单位1/1000英寸
            //PTXLIB.PTXA_FormSetup(2, 1);//设置打印数量为1

            // Create the label object
            int lForm = PTXLIB.PTXA_CreateForm("T4000Form");

            /* ALPHA - Default ASCII font */
            int resultOfPrintText = PTXLIB.PTXA_PrintTextEng(lForm, 2, 4, 0, 0, $"{data}");

            /* 打印中文 */
            //int result = PTXLIB.PTXA_PrintTextCH(lForm, 3, 4, 0, 0, $"DT乘客饰条");

            /* BARCODES 条码暂不需要了 */
            //int resultOfSetBarcode = PTXLIB.PTXA_SetBarcode(PTX_Constants.PTXA_BCD_C128C, PTX_Constants.PTXA_BCDOptParam_HEIGHT, "4");
            //int resultOfPrintBarcode = PTXLIB.PTXA_PrintBarcode(lForm, PTX_Constants.PTXA_BCD_C128C, 3, 3, data);

            /* RFID */
            //int resultOfSetupRFID = PTXLIB.PTXA_SetupRFID(48, false, "H", 0, data);
            int resultOfSetupRFID = PTXLIB.PTXA_SetupRFID(96, false, "H", 0, data + "FFFFFFFF");
            int resultOfWriteRFID = PTXLIB.PTXA_WriteRFID(lForm, "", "EPC");

            /* PRINT THE LABEL */
            nint resultOfPrintForm = PTXLIB.PTXA_PrintForm(lForm);

            int resultOfVerifyRFID = PTXLIB.PTXA_VerifyRFID(lForm, "", "TID", 48, "H");

            /* CLOSE THE CONNECTION */
            int resultOfClosePort = PTXLIB.closeport();

            /* CLOSE THE DLL */
            //PTXLIB.PTXA_DLLexit();

            return response;
        }

        //private PagedResultDto<PlasticContainerDto> Mapping(IQueryable<PlasticContainer> entity, int totalCount)
        //{
        //    DateTime dateTime;
        //    // 将实体转换为DTO
        //    List<PlasticContainerDto> dtos = entity.Select(l => new PlasticContainerDto
        //    {
        //        Id = l.Id,
        //        RFID = l.RFID,
        //        Status = l.Status
        //    }).ToList();
        //    var result = new PagedResultDto<PlasticContainerDto>
        //    {
        //        TotalCount = totalCount,
        //        Items = dtos
        //    };
        //    return result;
        //}

        private enum ReturnValue
        {
            PTXA_INVALID,
            PTXA_OK
        }
    }
}
